package com.ungao.servlet;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.URI;

public final class HttpServletResponse {

    private Headers responseHeaders;
    private URI requestURI;
    private OutputStream responseBody;
    private HttpExchange httpExchange;

    public HttpServletResponse(HttpExchange httpExchange) {
        this.httpExchange = httpExchange;
        this.responseHeaders = httpExchange.getResponseHeaders();
        this.requestURI = httpExchange.getRequestURI();
        this.responseBody = httpExchange.getResponseBody();
    }

    public Headers getResponseHeaders() {
        return this.responseHeaders;
    }

    public URI getRequestURI() {
        return requestURI;
    }

    public OutputStream getResponseBody() {
        return this.responseBody;
    }

    public void sendRedirect(String location) throws IOException {
        this.responseHeaders.add("Location", location);
        this.sendResponseHeaders(302, 0);
    }

    public void sendResponseHeaders(int statusCode, long contentLength) throws IOException {
        this.httpExchange.sendResponseHeaders(statusCode, contentLength);
    }

    public void sendError(Object content) throws Exception {
        byte[] bytes = this.toByteArray(content);
        httpExchange.getResponseHeaders().add("Content-Type", "text/html; charset=UTF-8");
        httpExchange.sendResponseHeaders(500, bytes.length);
        this.getResponseBody().write(bytes);
    }

    public void write(Object content) throws Exception {
        byte[] bytes = this.toByteArray(content);
        httpExchange.sendResponseHeaders(200, bytes.length);
        this.getResponseBody().write(bytes);
        this.getResponseBody().flush();
    }

    public byte[] toByteArray(Object content) throws Exception {
        byte[] bytes = new byte[]{};
        if (content instanceof Integer) {
            bytes = new byte[]{((Integer) content).byteValue()};
        } else if (content instanceof String) {
            bytes = ((String) content).getBytes("UTF-8");
        } else if (content instanceof Double) {
            bytes = new byte[]{((Double) content).byteValue()};
        } else if (content instanceof Float) {
            bytes = new byte[]{((Float) content).byteValue()};
        } else if (content instanceof Long) {
            bytes = new byte[]{((Long) content).byteValue()};
        } else {
            try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
                 ObjectOutputStream oos = new ObjectOutputStream(bos)) {
                if (content instanceof Boolean) {
                    oos.writeBoolean((Boolean) content);
                } else {
                    oos.writeObject(content);
                }
                oos.flush();
                bytes = bos.toByteArray();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return bytes;
    }
}
